﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Web;
using MetaCollection.Framework.Model;

namespace MetaCollection.ContentService.Render
{

	public class RenderImage
	{

		public void ProcessRequest(HttpContext context, IItemInstance item)
		{
			
		}


		/// <summary>
		/// Scales the image.
		/// </summary>
		/// <param name="binaryData">The binary data.</param>
		/// <param name="maxWidth">Width of the max.</param>
		/// <param name="maxHeight">Height of the max.</param>
		/// <param name="isIcon">if set to <c>true</c> [is icon].</param>
		/// <param name="captionText">The caption text.</param>
		/// <returns></returns>
		public static byte[] ScaleImage(byte[] binaryData, int maxWidth, int maxHeight, bool isIcon, string captionText)
		{			
			using (Bitmap myBitmap = new Bitmap(new MemoryStream(binaryData)))
			{
				ThumbInfo thumb = new ThumbInfo(new Size(myBitmap.Width, myBitmap.Height), new Size(maxWidth, maxHeight));
				Font captionFont = new Font("Lucidia Console", 10, GraphicsUnit.Pixel);
				SolidBrush captionBrush = new SolidBrush(Color.White);
				StringFormat captionFormat = new StringFormat(StringFormatFlags.NoWrap);
								 
				MemoryStream mout = new MemoryStream();
				EncoderParameter ratio = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 80L);
				EncoderParameters codecParams = new EncoderParameters(1);
				codecParams.Param[0] = ratio;
				Bitmap scaledImage;
				Graphics glyph;
				if (isIcon)
				{
					scaledImage = new Bitmap(thumb.MaxWidth, thumb.MaxHeight, PixelFormat.Format32bppArgb);
					scaledImage.MakeTransparent();
					glyph = Graphics.FromImage(scaledImage);
					glyph.FillRectangle(Brushes.White, thumb.MaxRectangle);
					glyph.DrawRectangle(Pens.DarkGray, 0, 0, thumb.MaxWidth - 1, thumb.MaxHeight - 1);
					glyph.DrawImage(myBitmap, thumb.CenterRectangle);
				}
				else
				{
					scaledImage = new Bitmap(thumb.AdjustedSize.Width, thumb.AdjustedSize.Height, PixelFormat.Format32bppArgb);
					scaledImage.MakeTransparent();
					glyph = Graphics.FromImage(scaledImage);
					glyph.InterpolationMode = InterpolationMode.HighQualityBicubic;
					glyph.SmoothingMode = SmoothingMode.HighQuality;
					glyph.PixelOffsetMode = PixelOffsetMode.HighQuality;
					glyph.CompositingQuality = CompositingQuality.HighQuality;
					glyph.DrawImage(myBitmap, new Rectangle(new Point(0, 0), thumb.AdjustedSize));
				}

				//Process the image caption if needed.
				if (thumb.Height > 75 && thumb.Width > 75)
				{
					// Process the caption text glyph
					glyph.RotateTransform(-90);
					try
					{
						glyph.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
						// Sample colors for brightness check.
						float strWidth = glyph.MeasureString(captionText, captionFont).Width;
						float colorSample = myBitmap.GetPixel(myBitmap.Width - 5, myBitmap.Height - (int)(strWidth / 5)).GetBrightness();
						colorSample += myBitmap.GetPixel(myBitmap.Width - 5, myBitmap.Height - (int)(strWidth / 5) * 2).GetBrightness();
						colorSample += myBitmap.GetPixel(myBitmap.Width - 5, myBitmap.Height - (int)(strWidth / 5) * 3).GetBrightness();
						colorSample += myBitmap.GetPixel(myBitmap.Width - 5, myBitmap.Height - (int)(strWidth / 5) * 4).GetBrightness();
						colorSample += myBitmap.GetPixel(myBitmap.Width - 5, myBitmap.Height - (int)strWidth).GetBrightness();
						if ((colorSample / 5) > .5)
							captionBrush.Color = Color.Black;
					}
					catch (IndexOutOfRangeException) { } // Ignore out of bounds sample error 
					catch (ArgumentException) { } // Ignore sample of invalid point (brightness of transparent for example)
					// If the caption will fit on the image then put it on...
					if (glyph.MeasureString(captionText, captionFont).Width < (float)thumb.Height)
						glyph.DrawString(captionText, captionFont, captionBrush, new PointF(-thumb.Height, thumb.Width - (captionFont.GetHeight() + 2)), captionFormat);

				}

				scaledImage.Save(mout, GetEncoderInfo("image/jpeg"), codecParams);
				return mout.GetBuffer();
			}
		}

		/// <summary>
		/// Gets the encoder info.
		/// </summary>
		/// <param name="mimeType">Type of the MIME.</param>
		/// <returns></returns>
		static ImageCodecInfo GetEncoderInfo(String mimeType)
		{
			int j;
			ImageCodecInfo[] encoders;
			encoders = ImageCodecInfo.GetImageEncoders();
			for (j = 0; j < encoders.Length; ++j)
			{
				if (encoders[j].MimeType == mimeType)
					return encoders[j];
			} return null;
		}

	 
		class ThumbInfo
		{
			int _width;
			int _height;
			int _maxWidth;
			int _maxHeight;
			/// <summary>
			/// 
			/// </summary>
			double _aRatio;

			/// <summary>
			/// Creates a new instance of the Thumbnail Information class
			/// </summary>
			/// <param name="current">The current size of the image.</param>
			/// <param name="maxSize">max size of the thumbnail.</param>
			public ThumbInfo(Size current, Size maxSize)
			{
				_width = current.Width;
				_height = current.Height;
				_maxWidth = ((maxSize.Width == 0) ? _width : maxSize.Width);
				_maxHeight = ((maxSize.Height == 0) ? _height : maxSize.Height);
				_aRatio = (double)_width / (double)_height;

				if ((_width > _maxWidth) && (_maxWidth > 0))
				{
					_width = _maxWidth;
					_height = Convert.ToInt32(_width / _aRatio);
				}
				if ((_height > _maxHeight) && (_maxHeight > 0))
				{
					_height = _maxHeight;
					_width = Convert.ToInt32(_height * _aRatio);
				}
			}
			/// <summary>
			/// Maximum image width
			/// </summary>
			public int MaxWidth { get { return _maxWidth; } }
			/// <summary>
			/// Maximum image height
			/// </summary>
			public int MaxHeight { get { return _maxHeight; } }
			/// <summary>
			/// Image height
			/// </summary>
			public int Height { get { return _height; } }
			/// <summary>
			/// Image width
			/// </summary>
			public int Width { get { return _width; } }
			/// <summary>
			/// Returns a point for which the image at the preserved aspect would need to be placed to appear
			/// in the middle of the requested max width and height.
			/// </summary>
			public Point CenterPoint { get { return new Point((int)((MaxWidth - Width) / 2), (int)((MaxHeight - Height) / 2)); } }
			/// <summary>
			/// Center rectangle for a scaled image which would be centered on an thumbnail of the MaxSize
			/// </summary>
			public Rectangle CenterRectangle { get { return new Rectangle(CenterPoint.X + 2, CenterPoint.Y + 2, AdjustedSize.Width - 4, AdjustedSize.Height - 4); } }
			/// <summary>
			/// Maximum size rectangle of the image thunbnail
			/// </summary>
			public Size MaxSize { get { return new Size(_maxWidth, _maxHeight); } }

			public Rectangle MaxRectangle { get { return new Rectangle(new Point(0, 0), MaxSize); } }
			/// <summary>
			/// Adjusted image size (if MaxSize forces image size scaling)
			/// </summary>
			public Size AdjustedSize { get { return new Size(_width, _height); } }
		}

		
	}
}
